﻿using System;
using System.Linq;
using RAP.Framework.Libary.Utils;
using System.Collections;
using RAP.Framework.Libary.DomTemplateBuilder.Handler.Parameter;
using RAP.Framework.Libary.DomTemplateBuilder.Interface;

namespace RAP.Framework.Libary.DomTemplateBuilder.ContentRender.Pattern
{
  /// <summary>
  /// 正则表达式处理器基类
  /// </summary>
  public abstract class PatternRenderBase : IContentRender
  {
    /// <summary>
    /// 正则表达式
    /// </summary>
    public virtual string Pattern { get; set; }

    /// <summary>
    /// 名称
    /// </summary>
    public virtual string Name { get; set; }

    /// <summary>
    /// 
    /// </summary>
    protected TemplateTranslator translator;

    /// <summary>
    /// 
    /// </summary>
    protected TemplateTranslator Translator
    {
      get
      {
        if (translator == null)
        {
          translator = new TemplateTranslator(this.Pattern, true);
        }
        return translator;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="rootParamObject"></param>
    /// <param name="parentParamObject"></param>
    /// <param name="context"></param>
    /// <param name="fieldName"></param>
    /// <returns></returns>
    protected virtual object _getValueFun(object rootParamObject, object parentParamObject, ITemplateRenderContext context, string fieldName)
    {
      object value = null;
      var paramName = string.Empty;
      var isParam = false;
      // 获取输出类型
      var isOutputString = fieldName.LastIndexOf('*') > 0;  //如果字段以 * 结尾，则表示按字符串输出
      if (isOutputString)
      {
        fieldName = fieldName.RightSubstring('*');
      }

      // 获取默认值
      var hasOrFlag = fieldName.LastIndexOf(Consts.OR_FLAG) > 0;
      string defaultValue = null;
      if (hasOrFlag)
      {
        defaultValue = fieldName.RightEndString(Consts.OR_FLAG);
        fieldName = fieldName.LeftSubstring(Consts.OR_FLAG);
      }

      // 获取变量别名
      if (fieldName.IndexOf(Consts.COLON_FLAG) > 0)
      {
        //获取参数别名
        var arr = fieldName.Split(new string[] { Consts.COLON_FLAG }, StringSplitOptions.RemoveEmptyEntries);
        fieldName = arr.First();
        paramName = arr.Last<string>();
        isParam = paramName.IsNotNullOrEmpty();
      }

      if (fieldName == Consts.VALUE_PREFIX || fieldName == Consts.PARENT_PREFIX)
      {
        value = parentParamObject;
      }
      else if (fieldName == Consts.ROOT_PREFIX || fieldName == Consts.PARAM_PREFIX)
      {
        value = rootParamObject;
      }
      else if (fieldName == Consts.CONTEXT_PREFIX)
      {
        value = context;
      }
      else if (fieldName == Consts.CURRENT_ATTRIBUTES)
      {
        value = context.CurrentAttributes;
      }
      else if (fieldName.StartsWith(Consts.ROOT_PREFIX))
      {
        value = rootParamObject.GetValue(fieldName.Substring(Consts.ROOT_PREFIX.Length + 1));
      }
      else if (fieldName.StartsWith(Consts.PARAM_PREFIX))
      {
        value = rootParamObject.GetValue(fieldName.Substring(Consts.PARAM_PREFIX.Length + 1));
      }
      else if (fieldName.StartsWith(Consts.CONTEXT_PREFIX))
      {
        value = context.GetValue(fieldName.Substring(Consts.CONTEXT_PREFIX.Length + 1));
      }
      else if (fieldName.StartsWith(Consts.PARENT_PREFIX))
      {
        value = parentParamObject.GetValue(fieldName.Substring(Consts.PARENT_PREFIX.Length + 1));
      }
      else if (fieldName.StartsWith(Consts.CURRENT_ATTRIBUTES))
      {
        value = context.CurrentAttributes.GetValue(fieldName.Substring(Consts.CURRENT_ATTRIBUTES.Length + 1));
      }
      else if (fieldName.StartsWith(Consts.ALPHA_FLAG))
      {
        //如果是存粹的以@开头的字段
        fieldName = fieldName.Trim().Substring(1);
        value = parentParamObject.GetValue(fieldName);
        if (!isOutputString)
        {
          paramName = paramName.IsNullOrEmptyValue(() => fieldName.Replace('.', '_'));
          isParam = true;
        }
      }
      else
      {
        value = parentParamObject.GetValue(fieldName);
      }
      value = value.IsNullOrEmptyValue(defaultValue);
      if (isParam)
      {
        paramName = ParameterHandler.AddContextParameter(context, paramName, value);
        value = $"@{paramName}";
      }
      return value;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="content"></param>
    /// <param name="rootParamObject"></param>
    /// <param name="parentParamObject"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    public virtual string DoRender(string content, object rootParamObject, object parentParamObject, ITemplateRenderContext context)
    {
      Func<string, object> getValueFun = (string fieldName) =>
      {
        return _getValueFun(rootParamObject, parentParamObject, context, fieldName);
      };
      content = this.Translator.TranslateTemplate(content, getValueFun);
      getValueFun = null;
      return content;
    }

    /// <summary>
    /// 编译指定模板
    /// </summary>
    /// <param name="content"></param>
    /// <returns></returns>
    public virtual Func<object, object, ITemplateRenderContext, string> CompileRender(string content)
    {
      Func<Func<string, string>, string> compiledFunc = null;
      this.Translator.CompileTemplate(content, out compiledFunc);
      return (root, parent, ctx) =>
      {
        return compiledFunc((fieldName) =>
        {
          object obj = _getValueFun(root, parent, ctx, fieldName);
          return obj.IsNullOrEmpty() ? null : obj.ToString();
        });
      };
    }
  }
}
